#include "stdafx.h"
#include <algorithm>
#include "UIManagerImpl.h"
#include "UIImgGdiplus.h"
#include "UIFrame.h"
#include "UILayout.h"
#pragma comment(lib,"gdiplus.lib")

GdiplusStartupInput    CUIManagerImpl::m_Gdistart;
ULONG_PTR    CUIManagerImpl::m_GdiplusToken;

map<HWND, CUIWindow*> CUIManagerImpl::m_WindowObjMap;
vector<LPCTSTR> CUIManagerImpl::m_RegisterWndClassMap;

CUIManagerImpl::CUIManagerImpl()
{
    RegisterAllWindowClass();
}

CUIManagerImpl::~CUIManagerImpl()
{
    map<HWND, CUIWindow*>::iterator it = m_WindowObjMap.begin();

    for ( it; it != m_WindowObjMap.end(); it++ )
    {
        CUIWindow* pWnd = ( CUIWindow* )( it->second );

        if ( NULL != pWnd )
        {
            UnHookWindow( pWnd );
            UnSkinWnd( pWnd->GetHwnd() );
            delete pWnd;
            pWnd = NULL;
        }
    }
}

CUIImgInterface* CUIManagerImpl::CreateUIImgRender()
{
    return NULL;
//	return new CUIImgGdiplus();
}

CUILayout* CUIManagerImpl::CreateUILayout()
{
    return new CUILayout();
}

CUIWindow* CUIManagerImpl::SkinWnd( HWND hWnd )
{
    CUIWindow* pWindow = CreateUIWindow( hWnd );

    if ( NULL != pWindow )
    {
        if ( !pWindow->IsSkined() )
        {
            if ( HookWindow( pWindow ) )
                return pWindow;
            else
            {
                delete pWindow;
                pWindow = NULL;
            }
        }
    }

    return pWindow;
}

void CUIManagerImpl::UnSkinWnd( HWND hWnd )
{
    m_WindowObjMap.erase( hWnd );
}

BOOL CUIManagerImpl::HookWindow( CUIWindow* pWnd )
{
    WNDPROC OldWndProc = ( WNDPROC )::GetWindowLong( pWnd->GetHwnd(), GWL_WNDPROC );
    pWnd->SaveOldWindowProc( OldWndProc );
    ::SetWindowLong( pWnd->GetHwnd(), GWL_WNDPROC, ( LONG )NewWindowProc );
    m_WindowObjMap.insert( pair<HWND, CUIWindow*>( pWnd->GetHwnd(), pWnd ) );
    return TRUE;
}

void CUIManagerImpl::UnHookWindow( CUIWindow* pWnd )
{
    WNDPROC oldWndProc = pWnd->GetOldWindowProc();

    if ( NULL != oldWndProc )
    {
        ::SetWindowLong( pWnd->GetHwnd(), GWL_WNDPROC, ( LONG )oldWndProc );
    }

    pWnd->SaveOldWindowProc( NULL );
}

CUIWindow* CUIManagerImpl::CreateUIWindow( HWND hWnd )
{
    CUIWindow* pWindow = FromeHandle( hWnd );

    if ( NULL != pWindow )
    {
        return pWindow;
    }

    TCHAR sClassName[32] = {0};
    ::GetClassName( hWnd, sClassName, 32 );

    if ( _tcscmp( sClassName, _T( "tooltips_class32" ) ) == 0 )
        return NULL;

    if ( _tcsicmp( sClassName, _T( "IME" ) ) == 0 )
        return NULL;

    if ( _tcsicmp( sClassName, _T( "CicMarshalWndClass" ) ) == 0 )
        return NULL;

    if ( _tcsicmp( sClassName, _T( "MSCTFIME UI" ) ) == 0 )
        return NULL;

    if ( _tcsstr( sClassName, _T( "Internet Explorer" ) ) != NULL )
        return NULL;

    if ( _tcsstr( sClassName, _T( "OleMainThread" ) ) != NULL )
        return NULL;

//	if (0==_tcscmp(sClassName,_T("#32770")))
    {
//		pWindow=new CUIFrame(hWnd);
    }
    return pWindow;
}

CUIWindow* CUIManagerImpl::FromeHandle( HWND hWnd )
{
    map<HWND, CUIWindow*>::iterator it = m_WindowObjMap.begin();

    for ( it; it != m_WindowObjMap.end(); it++ )
    {
        if ( it->first == hWnd )
        {
            return ( CUIWindow* )( it->second );
        }
    }

    return NULL;
}

UINT CUIManagerImpl::NewWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    CUIWindow* pWnd = FromeHandle( hWnd );

    if ( NULL != pWnd )
    {
        return pWnd->ProcessUIMsg( uMsg, wParam, lParam );
    }

    return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
}

void CUIManagerImpl::RegisterWindowClass( LPCTSTR lpszWndClassName )
{
    if ( !WindowClassRegistered( lpszWndClassName ) )
    {
        m_RegisterWndClassMap.push_back( lpszWndClassName );
    }
}

BOOL CUIManagerImpl::WindowClassRegistered( LPCTSTR lpszClassName )
{
    vector<LPCTSTR>::iterator it = find( m_RegisterWndClassMap.begin(), m_RegisterWndClassMap.end(), lpszClassName );
    return ( it != m_RegisterWndClassMap.end() );
}

void CUIManagerImpl::RegisterAllWindowClass()
{
    RegisterWindowClass( _T( "BUTTON" ) );
    RegisterWindowClass( _T( "EDIT" ) );
    RegisterWindowClass( _T( "#32770" ) );
    RegisterWindowClass( _T( "#32768" ) );
}

void CUIManagerImpl::Init()
{
    GdiplusStartup( &m_GdiplusToken, & m_Gdistart, NULL );
}

void CUIManagerImpl::UnInit()
{
    GdiplusShutdown( m_GdiplusToken );
}
